package br.com.minhasfinancas.fw.util;

import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.Set;

import javax.faces.application.FacesMessage;
import javax.faces.application.FacesMessage.Severity;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.model.SelectItem;

public class JSFUtil {

	private static final String BUNDLE_NAME = "br.com.minhasfinancas.web.messages.MessageResources";

	public static void sendInfoMessageToUser(String key, Object... params) {
		FacesMessage facesMessage = createMessage(FacesMessage.SEVERITY_INFO,
				getMessage(key, params));
		addMessageToJsfContext(facesMessage);
	}
	
	public static void sendWarnMessageToUser(String key, Object... params) {
		FacesMessage facesMessage = createMessage(FacesMessage.SEVERITY_WARN, getMessage(key, params));
		addMessageToJsfContext(facesMessage);
	}

	private static void addMessageToJsfContext(FacesMessage facesMessage) {
		FacesContext.getCurrentInstance().addMessage(null, facesMessage);
	}
	
	public static String getMessage(String key, Object... params) {
		ResourceBundle bundle = ResourceBundle.getBundle(BUNDLE_NAME, getFacesContext().getViewRoot().getLocale());
		if (params != null && params.length > 0) {
			return MessageFormat.format(bundle.getString(key), params);
		} else {
			return bundle.getString(key);
		}
	}
	
	private static FacesContext getFacesContext() {
		return FacesContext.getCurrentInstance();
	}
	
	private static FacesMessage createMessage(Severity severity, String message) {
		return new FacesMessage(severity, message, message);
	}
	public static void clearMessages() {
		FacesContext.getCurrentInstance().getExternalContext().getFlash().clear();
	}

	public static <T> List<T> convertArrayToList(final T[] arr) {
		if (arr == null) {
			return new ArrayList<T>();
		}
		return Arrays.asList(arr);
	}

	public static <T> Set<T> convertArrayToSet(final T[] arr) {
		if (arr == null) {
			return new HashSet<T>();
		}
		return new HashSet<T>(Arrays.asList(arr));
	}

	public static Object[] convertCollectionToArray(final Collection<?> c) {
		if (c == null) {
			return new Object[0];
		}
		return c.toArray();
	}

	public static <T> List<T> convertSetToList(final Set<T> set) {
		return new ArrayList<T>(set);
	}


	public static String getAsConvertedString(final Object object, final Converter converter) {
		return converter.getAsString(FacesContext.getCurrentInstance(), null, object);
	}

	public static ResourceBundle getBundle() {
		final FacesContext facesContext = FacesContext.getCurrentInstance();
		return FacesContext.getCurrentInstance().getApplication().getResourceBundle(facesContext, "messages");
	}

	public static String getCollectionAsString(final Collection<?> collection) {
		if ((collection == null) || (collection.size() == 0)) {
			return "(Sem itens)";
		}
		final StringBuffer sb = new StringBuffer();
		int i = 0;
		for (final Object item : collection) {
			if (i > 0) {
				sb.append("<br />");
			}
			sb.append(item);
			i++;
		}
		return sb.toString();
	}

	public static String getMessageFromResourceBundle(final String key) {
		String result = null;
		try {
			result = getBundle().getString(key);
		} catch (final MissingResourceException e) {
			result = key;
		}
		return result;
	}

	public static String getMessageFromResourceBundle(final String key, final Object... params) {
		String messageFromResourceBundle = getMessageFromResourceBundle(key);

		if (params != null) {
			messageFromResourceBundle = MessageFormat.format(messageFromResourceBundle, params);
		}

		return messageFromResourceBundle;
	}

	public static Object getObjectFromRequestParameter(final String requestParameterName, final Converter converter, final UIComponent component) {
		final String theId = JSFUtil.getRequestParameter(requestParameterName);
		return converter.getAsObject(FacesContext.getCurrentInstance(), component, theId);
	}

	public static String getRequestParameter(final String key) {
		return FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get(key);
	}

	public static SelectItem[] getSelectItems(final List<?> entities, final boolean selectOne) {
		final int size = selectOne ? entities.size() + 1 : entities.size();
		final SelectItem[] items = new SelectItem[size];
		int i = 0;
		if (selectOne) {
			items[0] = new SelectItem("", "---");
			i++;
		}
		for (final Object x : entities) {
			items[i++] = new SelectItem(x, x.toString());
		}
		return items;
	}


	public static void redirect(final String url) {
		try {
			FacesContext.getCurrentInstance().getExternalContext().redirect(url);
		} catch (final IOException e) {
			sendWarnMessageToUser("Não foi possível redirecionar para a url solicitada. " + e.getMessage());
		}
	}

}